<!DOCTYPE html>
<html lang="en">
    <head>
        <meta
            name="viewport"
            content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
        />
        <meta charset="UTF-8" />
        <title>Labyrinth</title>
        <style>
            .rebuild {
                width: 160px;
                height: 40px;
                line-height: 40px;
                text-align: center;
                background-color: #000000;
                color: #fff;
                font-size: 24px;
                margin-bottom: 20px;
                cursor: pointer;
            }
            .box-row {
                display: flex;
            }

            .box {
                border: 1px solid #222;
                height: 20px;
                width: 20px;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div @click="reset" class="rebuild">重置迷宫</div>
            <input type="number" min="3" v-model="height" />
            <input type="number" min="3" v-model="width" />
            <div>
                <div
                    class="box-row"
                    v-for="(row,index) in labyrinth"
                    :key="index"
                >
                    <div
                        class="box"
                        :style="{
                            backgroundColor:color[box]
                        }"
                        v-for="(box,index1) in row"
                        :key='index+"-"+index1'
                        :data-pos='index+"-"+index1'
                    ></div>
                </div>
            </div>
        </div>
    </body>

    <script type="module">
        import { createMaze, findPath } from "../dist/index.js";
        import Vue from "https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.esm.browser.min.js";
        import random from "https://cdn.skypack.dev/loadsh/random.js";
        new Vue({
            el: "#app",
            data() {
                return {
                    labyrinth: [[]],
                    height: 7,
                    width: 7,
                    color: ["white", "black", "red"],
                    mainline: Promise.resolve(1),
                };
            },
            mounted() {
                this.reset();
            },
            watch: {
                width() {
                    this.reset();
                },
                height() {
                    this.reset();
                },
            },
            methods: {
                reset() {
                    this.labyrinth = createMaze(
                        parseInt(this.height),
                        parseInt(this.width)
                    );
                    console.log("布局完成");
                    this.find();
                },
                genRandPoint() {
                    return [
                        random(1, this.labyrinth),
                        random(1, this.labyrinth[0].length),
                    ];
                },
                getVal(x, y) {
                    return this.labyrinth[x][y];
                },

                changeColor([x, y]) {
                    this.mainline = this.mainline.then(
                        () =>
                            new Promise((resolve, reject) => {
                                setTimeout(() => {
                                    this.labyrinth[x][y] = 2;
                                    this.$forceUpdate();
                                    resolve();
                                }, 100);
                            })
                    );
                },
                find() {
                    const start = [1, 1];
                    const end = [13, 13];
                    this.changeColor(start);
                    this.changeColor(end);
                    console.log(start, end);
                    const path = findPath({
                        start: {
                            x: start[0],
                            y: start[1],
                        },
                        end:{
                            x:end[0],
                            y:end[1],
                        },
                        // 自定义何处是墙
                        isWall: ({ x, y }) => {
                            // 需要越界保护
                            if (typeof this.labyrinth[x]?.[y] === "number") {
                                return this.labyrinth[x][y];
                            } else {
                                return true;
                            }
                        },
                        search({ x, y }) {
                            // 原先是进行八方位的查找,使用四方位查找即可
                            // 通过标记可以跳跃的点，甚至可以进行跳跃
                            const step = 1;
                            return [
                                [x - step, y],
                                [x + step, y],
                                [x, y + step],
                                [x, y - step],
                            ];
                        },
                    });
                    path.forEach(({ x, y }) => this.changeColor([x, y]));
                    console.log("寻路完成", path);
                },
            },
        });
    </script>
</html>
